import {
	Catch,
	ExceptionFilter,
	ArgumentsHost,
	HttpException,
	NotFoundException,
	HttpStatus,
	Logger,
	BadRequestException,
} from '@nestjs/common'
import { Response } from 'express'
import { sample } from 'lodash'
import { ErrorEnum } from '@/constants/error-code.constant'

/**
 *
 * BadRequestException (400)：当客户端发送的请求有错误或不能被服务器处理时，通常会抛出这个异常。
 * UnauthorizedException (401)：当请求需要用户认证信息，但用户未提供或提供的认证信息无效时，会抛出这个异常。
 * NotFoundException (404)：当请求的资源不存在时，例如，请求了一个不存在的路由或资源，通常会抛出这个异常。
 * ForbiddenException (403)：当服务器理解请求但拒绝执行时，通常因为权限不足，会抛出这个异常。
 * NotAcceptableException (406)：当请求的资源的MIME类型与服务器端不兼容时，会抛出这个异常。
 * RequestTimeoutException (408)：当服务器希望关闭一个未使用或空闲的连接时，会抛出这个异常。
 * ConflictException (409)：当请求与服务器当前状态冲突时（例如，请求修改的资源已被更改），会抛出这个异常。
 * GoneException (410)：当请求的资源已被永久删除且不再可用时，会抛出这个异常。
 * PayloadTooLargeException (413)：当请求提交的数据大小超过服务器愿意或能够处理的限制时，会抛出这个异常。
 * UnsupportedMediaTypeException (415)：当请求消息的格式不受请求资源的支持时，会抛出这个异常。
 * InternalServerErrorException (500)：当服务器遇到意外情况，导致无法完成请求时，通常会抛出这个异常。
 * NotImplementedException (501)：当请求的功能服务器无法支持时，会抛出这个异常。
 * BadGatewayException (502)：当服务器作为网关或代理，从上游服务器收到无效响应时，会抛出这个异常。
 * ServiceUnavailableException (503)：当服务器不可用，通常是因为维护或超载时，会抛出这个异常。
 */

/** @name 通过异常过滤器统一异常格式 **/
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
	catch(exception: any, host: ArgumentsHost): void {
		console.log('app：异常过滤器')
		// 创建一个日志
		const logger = new Logger()
		// 在后台输出日志
		logger.error(exception)

		const ctx = host.switchToHttp()
		const response = ctx.getResponse<Response>()

		const statusCode: number = HttpStatus.OK
		let code: number = HttpStatus.INTERNAL_SERVER_ERROR
		let msg: string = '服务繁忙，请稍后再试'

		if (exception instanceof HttpException) {
			const exceptionResponse = exception.getResponse() as { message: string[] }
			code = exception.getStatus()
			if (exception instanceof NotFoundException) {
				msg = '请求不存在'
			} else if (exceptionResponse.message) {
				msg = exceptionResponse?.message?.join ? exceptionResponse?.message?.join(',') : exception.message
			}
		}

		response.status(statusCode).json({
			code,
			msg,
		})
	}
}
